/*
 * CcType.h
 *
 *  Created on: 2012/04/28
 *      Author: guanxiaoying
 */

#ifndef CCTYPE_H_
#define CCTYPE_H_

#define TYPE_NOTBASIC 0
#define TYPE_VOID 1
#define TYPE_CHAR 2
#define TYPE_SIGNED_CHAR 3
#define TYPE_UNSIGNED_CHAR 4
#define TYPE_SHORT 5
#define TYPE_SIGNED_SHORT 6
#define TYPE_UNSIGNED_SHORT 7
#define TYPE_INT  8
#define TYPE_SIGNED_INT 9
#define TYPE_UNSIGNED_INT 10
#define TYPE_LONG 11
#define TYPE_SIGNED_LONG 12
#define TYPE_UNSIGNED_LONG 13
#define TYPE_LONG_LONG 14
#define TYPE_SIGNED_LONG_LONG 15
#define TYPE_UNSIGNED_LONG_LONG 16
#define TYPE_FLOAT 17
#define TYPE_DOUBLE 18
#define TYPE_LONG_DOUBLE 19



#define SIGN_NOTHING		0x00	/* 符号ありでも符号なしでもない	*/
#define SIGN_SIGNED			0x01	/* 符号あり変数型			*/
#define SIGN_UNSIGNED		0x02	/* 符号なし変数型		*/
#define SIGN_SPECIFY_SIGNED		(SIGN_SPECIFY_SIGNED_FLAG|SIGN_SIGNED)	/* signedが指定された		*/
#define SIGN_SPECIFY_UNSIGNED	(SIGN_SPECIFY_UNSIGNED_FLAG|SIGN_UNSIGNED)	/* unsignedが指定された	*/
#define SIGN_SPECIFY_SIGNED_FLAG 0x04
#define SIGN_SPECIFY_UNSIGNED_FLAG	0x08

/*  精度　*/
#define LENGTH_NOTHING	0
#define LENGTH_SHORT		1		/* S2変数			*/
#define LENGTH_LONG		2		/* S4変数			*/
#define LENGTH_LONGLONG		4		/* S4変数			*/

/* 型修飾子 */
#define TYPEQUAL_NONE  			0x00
#define TYPEQUAL_CONST  		0x01
#define TYPEQUAL_VOLATILE  		0x02
#define TYPEQUAL_RESTRICT  		0x04
#define TYPEQUAL_CONVOL  		(TYPEQUAL_CONST|TYPEQUAL_VOLATILE)

/* 整数小数フラグ　*/
#define FLOATING_NOTHING		0	/*!< なし			*/
#define FLOATING_INT		1	/*!< 整数				*/
#define FLOATING_FLOAT		2	/*!< 小数				*/

#define COMP_ASSIGN_ILLEGAL 0x0001
#define COMP_ASSIGN_UNCOMPATIBLE_POINTER 0x0002
#define COMP_ASSIGN_DIFFQUALIFY_POINTER  0x0004
#define COMP_ASSIGN_UNCOMPATIBLE 0x0008

#define  CcTypeIsConst( ast ) (TYPEQUAL_CONST&stTypeInfoAccess.typeQual.get(ast))
#define  CcTypeIsVolatile( ast ) (TYPEQUAL_VOLATILE&stTypeInfoAccess.typeQual.get(ast))
#define  CcTypeIsRestrict( ast ) (TYPEQUAL_RESTRICT&stTypeInfoAccess.typeQual.get(ast))

#define  CcTypeIsSigned( ast ) (SIGN_SIGNED & stTypeInfoAccess.signFlag.get( ast ))
#define  CcTypeIsUnSigned( ast ) (SIGN_UNSIGNED & stTypeInfoAccess.signFlag.get( ast ))
#define  CcTypeIsSpecifiedSigned( ast ) (SIGN_SPECIFY_SIGNED_FLAG & stTypeInfoAccess.signFlag.get( ast ))
#define  CcTypeIsSpecifiedUnSigned( ast ) (SIGN_SPECIFY_UNSIGNED_FLAG & stTypeInfoAccess.signFlag.get( ast ))

#define  CcTypeIsInteger( type ) (FLOATING_INT == stTypeInfoAccess.intFloat.get( type ))
#define  CcTypeIsFloating( type ) (FLOATING_FLOAT == stTypeInfoAccess.intFloat.get( type ))
#define  CcTypeIsArith( type ) (CcTypeIsInteger( type )||CcTypeIsFloating( type )||CcTypeIsEnum( type ) )
#define  CcTypeIsScalar( type )  (CcTypeIsInteger( type )||CcTypeIsFloating( type )||CcTypeIsEnum( type )||CcTypeIsPointer( type ))

/*debug,13/1/31,S*/
#define  CcTypeIsVoid(type)		(type==TYPE_VOID)
#define  CcCastTypeIsScalar(type)	\
	(CcTypeIsInteger( type )||CcTypeIsFloating( type )||CcTypeIsEnum( type )||CcTypeIsPointer( type ) || CcTypeIsVoid(type))
/*debug,13/1/31,E*/
#define  CcTypeIsLongLong( type ) (LENGTH_LONGLONG == stTypeInfoAccess.longShortFlg.get( type ))
#define  CcTypeIsLong( type ) (LENGTH_LONG == stTypeInfoAccess.longShortFlg.get( type ))
#define  CcTypeIsShort( type ) (LENGTH_SHORT == stTypeInfoAccess.longShortFlg.get( type ))

#define  CcTypeIsBasicType( type ) (stTypeInfoAccess.typeKind.get(type)==TYPEKIND_BASIC)
#define  CcTypeIsFunction( type ) (stTypeInfoAccess.typeKind.get(type)==TYPEKIND_FUNCTION)
#define  CcTypeIsArray( type ) (stTypeInfoAccess.typeKind.get(type)==TYPEKIND_ARRAY)
#define  CcTypeIsBitfield( type ) (TYPEKIND_BITFIELD == stTypeInfoAccess.typeKind.get( type ))
#define  CcTypeIsStruct( type ) (TYPEKIND_STRUCT == stTypeInfoAccess.typeKind.get( type ))
#define  CcTypeIsUnion( type ) (TYPEKIND_UNION == stTypeInfoAccess.typeKind.get( type ))
#define  CcTypeIsEnum( type ) (TYPEKIND_ENUM == stTypeInfoAccess.typeKind.get( type ))
#define  CcTypeIsPointer( type ) (TYPEKIND_POINTER == stTypeInfoAccess.typeKind.get( type ))

extern VOID CcTypeInitial( VOID );
extern AST CcTypeIntegerPromotion( AST type );
extern AST CcTypeGetArithConversion( AST type1, AST type2 );
extern AST CcTypeGetNoQualType( AST astType );
extern AST CcTypeGetBasicType( PSZ str, U2 typeQual  );
extern AST   CcTypeAddPointer( AST astBasic, U4 size, U2 qual );
extern AST   CcTypeAddArray( AST astBasic,U4 size );
extern AST   CcTypeResetArraySize( AST astArray, U4 newsize );
extern AST  CcTypeAddEnum( AST tagInfo, AST astBasicType, AST memChain );
extern AST  CcTypeAddDefaultEnum( AST astTagNameInfo );
extern AST  CcTypeAddQualifiedType( AST astBasicType, U2 qual );
extern AST  CcTypeAddStruct( AST tagInfo, AST memChain, U4 size );
extern AST  CcTypeAddUnion( AST tagInfo, AST memChain, U4 size);
extern AST  CcTypeAddFunction( AST returnType, AST memChain);
extern AST  CcTypeAddBitfield( AST intType, U4 size, U2 signFlag, U2 qual );
extern AST  CcTypeGetWCharType( VOID );
extern BOOL  CcTypeIsInt( AST type );
extern U2    CcTypeCreateQualifier( S2 constNum, S2 volatileNum, S2 restrictNum );
extern VOID  CcTypeSetUnionStructInfo(AST astTypeInfo, AST astParamChain, U4 ulSize );
extern BOOL CcTypeIsAssignable( AST astOrg, AST astDst );
extern BOOL CcTypeIsCompatible( AST astType1st, AST astType2nd );
extern AST CcTypeGetCompositeType( AST astType1st, AST astType2nd );
extern U4   CcTypeGetDefaultPointerSize( VOID );
extern BOOL CcTypeIsModifiableObj( AST astType );
extern U2   CcTypeCatchAssignableFlg( VOID );
extern U2   CcTypeCatchCompatibleFlg( VOID );
extern AST CcTypeGetObjMap( AST astType );
extern AST CcTypeArgumentPromotion( AST astArgExpType );
extern U4 CcTypeGetTypeSize( AST astType );
#endif /* CCTYPE_H_ */
